/*
 * v1.1 by tonydon
 * netbeansIDE 7.1
 */
package cn.txdnet.txweb.utils;

import java.lang.reflect.Method;
import java.util.*;
import org.apache.commons.io.IOUtils;
import txdnet.util.DataUtil;
import txdnet.util.Logger;
import txdnet.util.MethodUtil;
import txdnet.util.StaticMark;

/**
 *
 * @author txdnet
 */
public final class SiteActionMgr {

    // 存储action对象
    private static Map<String, Object> actionUrlCache = new HashMap<String, Object>();
    // 存储action对象方法
    private static Map<String, Method> actionMethodsCache = new HashMap<String, Method>();

    /**
     * 将action配置导入列表对象
     *
     * @param files
     * @return
     */
    private static List<ActionUrlBean> loadActionUrlConf(String... files) {
        String actionUrlConf;
        List<ActionUrlBean> list = new ArrayList<ActionUrlBean>();
        try {
            if (DataUtil.isEmpty(files)) {
                return Collections.emptyList();
            }
            List<ActionUrlBean> tmpList;
            for (String f : files) {
                if (DataUtil.isEmpty(f)) {
                    continue;
                }
                actionUrlConf = IOUtils.toString(SiteActionMgr.class
                        .getResourceAsStream(StaticMark.STR_SLASH.concat(f.trim()))).trim();
                // 去掉注释:
                actionUrlConf = WebUtil.clearNote(actionUrlConf);
                // 空配置文件跳过
                if (actionUrlConf.length() < 9) {
                    continue;
                }
                // JSON配置转为LIST<BEAN>
                tmpList = JsonUtil.parseArray(actionUrlConf, ActionUrlBean.class);
                list.addAll(tmpList);
            }
            Logger.debug(SiteActionMgr.class, "conf = ".concat(Arrays.toString(files)));
        } catch (Exception e) {
            Logger.error(SiteActionMgr.class, e.toString().concat(".loadActionUrlConf()"));
        }
        return list;
    }

    /**
     * 将列表对象及方法转为MAP进行缓存
     *
     * @param files
     * @throws Exception
     */
    public static void initActionUrlMap(String... files) throws Exception {
        List<ActionUrlBean> list = loadActionUrlConf(files);
        if (CollectionUtil.isEmpty(list)) {
            throw new RuntimeException("init action url error. not config action class .");
        }
        Object obj;
        for (ActionUrlBean bean : list) {
            if (bean == null || StringUtil.isEmpty(bean.getPath()) || StringUtil.isEmpty(bean.getClassname())) {
                continue;
            }
            obj = Class.forName(bean.getClassname()).newInstance();
            if (obj != null) {
                actionUrlCache.put(bean.getPath(), obj);
                initActionMethodMap(obj);
            }
        }
    }

    /**
     * 将Action对象方法缓存到Map
     *
     * @param action
     */
    private static void initActionMethodMap(Object action) {
        Method[] methods = action.getClass().getMethods();
        for (Method m : methods) {
            if (MethodUtil.isPublicMethod(m)) {
                String key = action.getClass().getCanonicalName().concat(StaticMark.STR_DOT).concat(m.getName());
                actionMethodsCache.put(key, m);
            }
        }
    }

    /**
     * 用于得到缓存的方法对象
     *
     * @param action
     * @param methodName
     * @return
     */
    public static Method getMethod(Object action, String methodName) {
        String key = action.getClass().getCanonicalName().concat(StaticMark.STR_DOT).concat(methodName);
        Method method = actionMethodsCache.get(key);
        if (method == null) {
            return null;
        }
        return method;
    }

    /**
     * 得到Action Execute Object
     *
     * @param urlAction
     * @return
     */
    public static Object getAction(String urlAction) {
        return actionUrlCache.get(urlAction);
    }

    /**
     * 销毁对象
     */
    public static void destroy() {
        actionUrlCache.clear();
        actionMethodsCache.clear();
        actionUrlCache = null;
        actionMethodsCache = null;
    }
}
